﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HerGoS.DAO;
using System.Data;
using HerGoS.Interfaces;
using HerGoS.Viaticos.Entities;
using HerGoS.Administration.Engine;
using HerGoS.Viaticos.Exceptions;
using HerGoS.Administration.Entities;

namespace HerGoS.Viaticos.Engine
{
    public class GestorLiquidacion
    {

        public static Liquidacion Obtener(int oid)
        {
            try
            {
                IRepository repo = RepositoryFactory.Create(Config.RepositoryViaticosName);
                repo.Nombre = "LIQUIDACIONES_SP";
                repo.AddParameter("@ACCION", "BYID");
                repo.AddParameter("@ID", oid);
                DataTable dt = repo.ExecuteDataTable();
                Liquidacion result = dt.ToGenericList<Liquidacion>(LiquidacionConverter).FirstOrDefault();
                return result;
            }
            catch (Exception ex)
            {
                throw new LiquidacionGetException(ex);
            }
        }

        public static void Guardar(Liquidacion liquidacion)
        {
            try
            {
                IRepository repo = RepositoryFactory.CreateTransactional(Config.RepositoryViaticosName);
                repo.Nombre = "LIQUIDACIONES_PROC";
                repo.AddParameter("@ACCION ", liquidacion.Persistencia);
                repo.AddParameter("@ID", liquidacion.OID);
                repo.AddParameter("@IDSOLICITUD", liquidacion.SolicitudLiquidada == null ?(int?)null :liquidacion.SolicitudLiquidada.OID );
                repo.AddParameter("@IDRENDICION", liquidacion.RendicionLiquidada == null ?(int?)null :liquidacion.RendicionLiquidada.OID );
                repo.AddParameter("@NUMERO", liquidacion.NumeroLiquidacion);
                repo.AddParameter("@DISTANCIA", liquidacion.Distancia == null ? (int?)null : liquidacion.Distancia.OID);
                repo.AddParameter("@IDENTIDAD", liquidacion.Entidad == null ? (int?)null : liquidacion.Entidad.OID);
                repo.AddParameter("@IDAREA", liquidacion.Area == null ? (int?)null : liquidacion.Area.OID);
                repo.AddParameter("@IDPERSONA", liquidacion.Persona == null ? (int?)null : liquidacion.Persona.OID);
                repo.AddParameter("@FECHA", liquidacion.FechaLiquidacion);// hace getdate()
                repo.AddParameter("@FECHASALIDA", liquidacion.FechaSalida);
                repo.AddParameter("@FECHARETORNO", liquidacion.FechaRetorno);
                repo.AddParameter("@OBSERVACIONES", liquidacion.Observaciones);
                repo.AddParameter("@VIATICOSFINSEMANA", liquidacion.ViaticosFindeSemana);
                repo.AddParameter("@ANTICIPO", liquidacion.Anticipo);
                repo.AddParameter("@PORCVIATICO", liquidacion.PorcentajeViatico);
                repo.AddParameter("@TOTALVIATICOS", liquidacion.TotalViaticos);
                repo.AddParameter("@TOTALTERMINALES", liquidacion.TotalTerminales);
                repo.AddParameter("@TOTALGASTOS", liquidacion.TotalGastos);
                repo.AddParameter("@ANTICIPOSLIQUIDADOS", liquidacion.AnticiposLiquidados);
                repo.AddParameter("@TOTALAPAGAR", liquidacion.TotalAPagar);
                repo.AddParameter("@NUMEROAP", liquidacion.NumeroAP);
                repo.AddParameter("@FECHAAP", liquidacion.FECHAAP);
                repo.AddParameter("@FECHAPAGO", liquidacion.FechaPago);
                repo.AddParameter("@MONTOPAGADO", liquidacion.MontoPagado);
                repo.AddParameter("@POA ", liquidacion.POA);
                repo.AddParameter("@CANTVIATICOS ", liquidacion.CantidadViaticos);
                repo.AddParameter("@TOTALKMRECORRIDOS", liquidacion.TotalKmRecorridos);
                repo.AddParameter("@CANTTERMINALES", liquidacion.CantidadTerminales);
                repo.AddParameter("@CANTKMS", liquidacion.CantidadKms);
                repo.AddParameter("@liqNUMEROCHEQUE", liquidacion.NumeroCheque);

                repo.AddParameter("@IDUSUARIO", HGSContext.Usuario.OID);
                liquidacion.OID = repo.ExecuteReturnValue().ToInteger();
                repo.Commit();
                 GestorBitacora.Guardar(liquidacion);

                GestorTramo.Guardar(liquidacion);

                GestorGasto.Guardar(liquidacion.LGastos,liquidacion.OID);


            }
            catch (Exception ex)
            {
                throw new LiquidacionSaveException(ex);
            }
        }




        public static List<Liquidacion> Consultar(Liquidacion liquidacion)
        {
            try
            {
                IRepository repo = RepositoryFactory.Create(Config.RepositoryViaticosName);
                repo.Nombre = "LIQUIDACIONES_SP";
                repo.AddParameter("@ACCION", "CONSULTA");
                repo.AddParameter("@ID", null);
                repo.AddParameter("@ACTIVO", liquidacion.Activo);
                repo.AddParameter("@IDUSUARIO", HGSContext.Usuario.OID);
                DataTable dt = repo.ExecuteDataTable();
                List<Liquidacion> result = dt.ToGenericList<Liquidacion>(LiquidacionConverter);
                return result;

            }
            catch (Exception ex)
            {
                throw new SolicitudGetException(ex);
            }
        }

        public static List<Liquidacion> Consultar()
        {
            return Consultar(new Liquidacion  { Activo = true });
        }


        public static void Eliminar(Liquidacion liquidacion)
        {
            liquidacion.Persistencia = EstadoPersistencia.DELETE;
            Guardar(liquidacion);
            liquidacion.Persistencia = EstadoPersistencia.UPDATE;
            liquidacion.Activo = false;
        }


        public static void ReActivar(Liquidacion liquidacion)
        {
            liquidacion.Persistencia = EstadoPersistencia.UNDELETE;
            Guardar(liquidacion);
            liquidacion.Persistencia = EstadoPersistencia.UPDATE;
            liquidacion.Activo = true;
        }

        public static Liquidacion TraerAnticipo(Solicitud solicitud)
        {
            try
            {
                IRepository repo = RepositoryFactory.Create(Config.RepositoryViaticosName);
                repo.Nombre = "SOLICITUDES_SP";
                repo.AddParameter("@ACCION", "TRAERANTICIPO");
                repo.AddParameter("@ID", solicitud.OID);
                repo.AddParameter("@ACTIVO", true);
                DataTable dt = repo.ExecuteDataTable();
                List<Liquidacion> result = dt.ToGenericList<Liquidacion>(LiquidacionConverter);
                return result.FirstOrDefault();

            }
            catch (Exception ex)
            {
                throw new SolicitudGetException(ex);
            }
        }




        #region Converter
        public static Liquidacion LiquidacionConverter(DataRow row)
        {
            Liquidacion liquidacion = new Liquidacion
            {
                OID = row["liqID"].ToInteger(),
                Persistencia = EstadoPersistencia.UPDATE,
                NumeroLiquidacion = row["liqNUMERO"].ToInteger(),
                SolicitudLiquidada = GestorSolicitudes.Obtener(row["liqIDSOLICITUD"].ToInteger()),
                RendicionLiquidada = GestorRendicion.Obtener(row["liqIDRENDICION"].ToInteger()),
                FechaLiquidacion = row["liqFECHA"].ToDateTime(),
                Entidad = GestorEntidades.Obtener(row["liqIDENTIDAD"].ToInteger()) ?? null,
                Area = GestorArea.Obtener(row["liqIDAREA"].ToInteger()) ?? null,
                Persona = GestorPersona.Obtener(row["liqIDPERSONA"].ToInteger()),
                Distancia = GestorDistancia.Obtener(row["liqDistancia"].ToInteger()),
                FechaSalida = row["liqFECHASALIDA"].ToNullableDateTime(),
                FechaRetorno = row["liqFECHARETORNO"].ToNullableDateTime(),
                ViaticosFindeSemana = row["liqVIATICOSFINSEMANA"].ToBoolean(),
                Anticipo = row["liqANTICIPO"].ToBoolean(),
                PorcentajeViatico = row["liqPORCVIATICO"].ToDecimal(),
                Observaciones = row["liqOBSERVACIONES"].ToString(),
                TotalViaticos = row["liqTOTALVIATICOS"].ToDecimal(),
                TotalTerminales = row["liqTOTALTERMINALES"].ToDecimal(),
                TotalGastos = row["liqTOTALGASTOS"].ToDecimal(),
                AnticiposLiquidados = row["liqANTICIPOSLIQUIDADOS"].ToDecimal(),
                TotalAPagar = row["liqTOTALAPAGAR"].ToDecimal(),
                NumeroAP = row["liqNUMEROAP"].ToString(),
                FECHAAP = row["liqFECHAAP"].ToNullableDateTime(),
                FechaPago = row["liqFECHAPAGO"].ToNullableDateTime(),
                MontoPagado = row["liqMONTOPAGADO"].ToDecimal(),
                POA = row["liqPOA"].ToString(),
                CantidadViaticos = row["liqCANTVIATICOS"].ToDecimal(),
                TotalKmRecorridos = row["liqTOTALKMRECORRIDOS"].ToDecimal(),
                CantidadTerminales = row["liqCANTERMINALES"].ToInteger(),
                CantidadKms = row["liqCANTKMS"].ToInteger(),
                NumeroCheque = row["liqNUMEROCHEQUE"].ToString(),
                Activo = row.IsNull("FECHA_BAJA") ? true : false
            };
            liquidacion.Tramos = GestorTramo.Consultar(liquidacion);
            liquidacion.LGastos = GestorGasto.Consultar(liquidacion);
            return liquidacion;
        }
        #endregion


    }
}
